<html>
<head><meta charset="utf-8"><title>UB to skip destructors · project-ffi-unwind · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/index.html">project-ffi-unwind</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html">UB to skip destructors</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="200296630"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200296630" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200296630">(Jun 09 2020 at 22:00)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> I'm still not quite clear on the reason why it's UB to skip destructors with <code>longjmp</code>. You wrote:</p>
<blockquote>
<p>In other words, it's true that unsafe code can <strong>actively cause</strong> destructors not to run, either by using <code>mem::forget</code> or by creating a <code>Rc</code> cycle.</p>
</blockquote>
<p><code>longjmp</code> is an "active" choice, too, and it requires <code>unsafe</code>. Unlike <code>mem::forget</code>, it has a non-local influence, but I think it's true in general of <code>unsafe</code> code. So the question of "is it UB" doesn't seem to be one of "should we break <code>rayon</code>?" but rather "is it the programmer's responsibility to avoid using <code>rayon</code> and <code>longjmp</code> in the same thread?" I believe the reasoning is the same for <code>pthread_exit</code>.</p>



<a name="200298511"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298511" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298511">(Jun 09 2020 at 22:20)</a>:</h4>
<p>I think I partially agree with that framing</p>



<a name="200298523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298523">(Jun 09 2020 at 22:20)</a>:</h4>
<p>It's true that I was conflating two different definitions of UB</p>



<a name="200298534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298534">(Jun 09 2020 at 22:20)</a>:</h4>
<p>i.e., there is a notion of "minimal UB" that must be avoided</p>



<a name="200298553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298553">(Jun 09 2020 at 22:20)</a>:</h4>
<p>but there is also a definition of "what can unsafe code assume other code won't do"</p>



<a name="200298565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298565">(Jun 09 2020 at 22:20)</a>:</h4>
<p>it's probably best not to think of that a single set</p>



<a name="200298581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298581">(Jun 09 2020 at 22:21)</a>:</h4>
<p>but still</p>



<a name="200298588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298588">(Jun 09 2020 at 22:21)</a>:</h4>
<p>if rayon is going to call itself <em>safe</em></p>



<a name="200298600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298600">(Jun 09 2020 at 22:21)</a>:</h4>
<p>that is implicitly quantified by some definition of limits on <em>unsafe code</em></p>



<a name="200298609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298609">(Jun 09 2020 at 22:21)</a>:</h4>
<p>and violating <em>those limits</em> is what I am calling "UB"</p>



<a name="200298625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298625">(Jun 09 2020 at 22:21)</a>:</h4>
<p>I'm not sure if there's an alternative term that e.g. the unsafe code guidelines has settled on</p>



<a name="200298714"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298714" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298714">(Jun 09 2020 at 22:22)</a>:</h4>
<p><a href="http://smallcultfollowing.com/babysteps/blog/2016/10/02/observational-equivalence-and-unsafe-code/">relevant blog post</a></p>



<a name="200298726"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298726" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298726">(Jun 09 2020 at 22:22)</a>:</h4>
<p>I don't think the answer of "it's the programmer's responsibility" is good enough, in other words, but it's also got truth in it</p>



<a name="200298785"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298785" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298785">(Jun 09 2020 at 22:23)</a>:</h4>
<p>in any case, the locality is the key bit -</p>



<a name="200298798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298798">(Jun 09 2020 at 22:23)</a>:</h4>
<p><code>mem::forget</code> can't cause somebody <em>else's</em> destructors not to run</p>



<a name="200298803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298803">(Jun 09 2020 at 22:23)</a>:</h4>
<p>but longjmp can</p>



<a name="200298862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298862">(Jun 09 2020 at 22:24)</a>:</h4>
<p>and you aren't really allowed to assume that other frames don't have dtors</p>



<a name="200298869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200298869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200298869">(Jun 09 2020 at 22:24)</a>:</h4>
<p>in particular frames can add them as a minor semver bump :)</p>



<a name="200299280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200299280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200299280">(Jun 09 2020 at 22:29)</a>:</h4>
<p>hmmmmmm</p>



<a name="200299296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200299296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200299296">(Jun 09 2020 at 22:29)</a>:</h4>
<p>that is true</p>



<a name="200299323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200299323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200299323">(Jun 09 2020 at 22:29)</a>:</h4>
<p>I am reminded of our discussion about "LLVM UB" versus other "UB" meanings</p>



<a name="200299616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200299616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200299616">(Jun 09 2020 at 22:33)</a>:</h4>
<p>And, as always, I think of "UB" as "the compiler has free reign to optimize in ways that break code"; so in this case, I am wondering, do we _want_ to give the compiler extra optimization potential by assuming that <code>longjmp</code> can never cross non-POFs?</p>



<a name="200300069"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200300069" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200300069">(Jun 09 2020 at 22:38)</a>:</h4>
<p>I guess the distinction I'm trying to draw is between "coding such a thing would be inherently broken, regardless of the compiler's optimizations" and "this code could hypothetically behave as you'd expect if the compiler doesn't optimize aggressively." Clearly there are instances where <code>longjmp</code> over non-POFs falls into the former category, but it seems like many or even most cases would fall into the latter.</p>



<a name="200300137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200300137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200300137">(Jun 09 2020 at 22:39)</a>:</h4>
<p>Obviously such a distinction is useless (or actively harmful) when writing code in a language, but I think it might be a helpful distinction when deciding whether a particular construct should be formally UB in the design of the language.</p>



<a name="200300228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200300228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200300228">(Jun 09 2020 at 22:40)</a>:</h4>
<p>I think much of Chandler Carruth's point here is that more UB than people realize falls into the first category rather than the second: <a href="https://youtu.be/yG1OZ69H_-o">https://youtu.be/yG1OZ69H_-o</a></p>
<div class="youtube-video message_inline_image"><a data-id="yG1OZ69H_-o" href="https://youtu.be/yG1OZ69H_-o"><img src="https://i.ytimg.com/vi/yG1OZ69H_-o/default.jpg"></a></div>



<a name="200300238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200300238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200300238">(Jun 09 2020 at 22:40)</a>:</h4>
<p>.....but I think it's pretty clear that C++ is also full of UB in the second category.</p>



<a name="200304231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304231">(Jun 09 2020 at 23:31)</a>:</h4>
<p>So I don't have time for a lengthy reply --</p>



<a name="200304246"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304246" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304246">(Jun 09 2020 at 23:31)</a>:</h4>
<p>but I just thought of one thing, and I'm going to cc <span class="user-mention" data-user-id="120791">@RalfJ</span> on this point,</p>



<a name="200304289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304289">(Jun 09 2020 at 23:32)</a>:</h4>
<p>if we say that a POF frame can be longjmp'd</p>



<a name="200304299"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304299" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304299">(Jun 09 2020 at 23:32)</a>:</h4>
<p>it occurs to me that if you have</p>



<a name="200304324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304324">(Jun 09 2020 at 23:32)</a>:</h4>
<div class="codehilite"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">*</span><span class="n">x</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">bar</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>then we can't move that <code>*x += 1</code> down below <code>bar()</code></p>



<a name="200304331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304331">(Jun 09 2020 at 23:32)</a>:</h4>
<p>I guess that may never have been something we planned to do anyway</p>



<a name="200304335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304335">(Jun 09 2020 at 23:32)</a>:</h4>
<p>I think mostly we've thought about pushing reads down below</p>



<a name="200304343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304343">(Jun 09 2020 at 23:33)</a>:</h4>
<p>but I'm not 100% sure about that, <span class="user-mention" data-user-id="120791">@RalfJ</span> would remember</p>



<a name="200304691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304691">(Jun 09 2020 at 23:37)</a>:</h4>
<p>Hmmmm.... that's a really interesting point.</p>



<a name="200304765"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304765" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304765">(Jun 09 2020 at 23:38)</a>:</h4>
<p>That definitely sounds like the sort of optimization that LLVM should "usually" be free to make.</p>



<a name="200304812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304812">(Jun 09 2020 at 23:39)</a>:</h4>
<p>....though, on second thought, that's probably not true, since that wouldn't be valid in C++ (since the compiler can't know whether there are other mutable references to <code>x</code> that may be accessed in the course of executing <code>bar()</code>).</p>



<a name="200304888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200304888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200304888">(Jun 09 2020 at 23:40)</a>:</h4>
<p>So that definitely seems like it invalidates an optimization that would be valid in Rust, but probably isn't done by LLVM as part of any "standard" optimization pass.</p>



<a name="200305182"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200305182" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200305182">(Jun 09 2020 at 23:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200304324">said</a>:</p>
<blockquote>
<p>then we can't move that <code>*x += 1</code> down below <code>bar()</code></p>
</blockquote>
<p>Without thinking too much about this, I believe this kind of transformation (and the reverse of moving assignments before function call) is only valid if <code>bar</code> is known to be side-effect free, and you need to take a conservative stance (i.e. it has side effects) if you can’t say otherwise. <code>bar</code> containing a <code>longjmp</code>, <code>panic!</code> etc, would make it side-effectful.</p>



<a name="200307720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200307720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200307720">(Jun 10 2020 at 00:26)</a>:</h4>
<p>That's a good point.</p>



<a name="200383459"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200383459" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200383459">(Jun 10 2020 at 06:54)</a>:</h4>
<p>I thought stacked borrows would enable exactly this kind of optimizations, as we know <code>bar</code> can't access <code>x</code> without violating the exclusiveness of the mutable reference. The compiler would have to revert the assignment on unwinding though.</p>



<a name="200414423"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200414423" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200414423">(Jun 10 2020 at 13:17)</a>:</h4>
<p><span class="user-mention" data-user-id="123586">@nagisa</span> it's true that, for panic, you would have to duplicate the effect on both paths, but it is in principle possible. longjmp is different, though, as there is no way to intervene. I recall that we've also discussed this question in the context of inter-process shared memory, where writes would be visible outside the process (and in that case, the transformation is simply not possible at all). There is a valid question then as to whether <code>&amp;mut</code> should be able to refer to shared memory. I sort of lean towards "yes" but that seems to imply a lot of limits on whether we can move writes.</p>



<a name="200414747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200414747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200414747">(Jun 10 2020 at 13:20)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120076">BatmanAoD (Kyle Strand)</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200299616">said</a>:</p>
<blockquote>
<p>And, as always, I think of "UB" as "the compiler has free reign to optimize in ways that break code"; so in this case, I am wondering, do we _want_ to give the compiler extra optimization potential by assuming that <code>longjmp</code> can never cross non-POFs?</p>
</blockquote>
<p>as far as the origin topic goes, I think we definitely ought to start distinguishing the question of "strict UB" versus "compositional UB". In other words, what kinds of things can we do but <em>only</em> if we control all the stack frames in between (longjmp may fall in that category, but as we pointed out here there is actually a choice being made in terms of potential optimizations that I don't think I at least was fully aware of).</p>



<a name="200444000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200444000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200444000">(Jun 10 2020 at 16:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200304343">said</a>:</p>
<blockquote>
<p>but I'm not 100% sure about that, <span class="user-mention silent" data-user-id="120791">RalfJ</span> would remember</p>
</blockquote>
<p>I think I am missing a lot of context here... what's a POF?</p>



<a name="200444047"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200444047" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200444047">(Jun 10 2020 at 16:55)</a>:</h4>
<p>I got pinged on <a href="https://github.com/rust-lang/project-ffi-unwind/pull/29#discussion_r438088431">https://github.com/rust-lang/project-ffi-unwind/pull/29#discussion_r438088431</a>, does that question subsume this one here?</p>



<a name="200444676"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200444676" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200444676">(Jun 10 2020 at 16:59)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> Not really, sorry! Niko's question here, as I understand it, is whether reordering mutations and function calls is something the compiler team has discussed permitting the optimizer to do.</p>



<a name="200445042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200445042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200445042">(Jun 10 2020 at 17:02)</a>:</h4>
<p>The linked PR does explain the "POF" terminology, though. (If you would like to see the discussion that led to that term, it's here: <a href="#narrow/stream/210922-project-ffi-unwind/topic/posting.20the.20RFc/near/197461120">https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/posting.20the.20RFc/near/197461120</a>. And of course feel free to opine on the subject, especially if you can do so before the RFC is posted.)</p>



<a name="200445505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200445505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200445505">(Jun 10 2020 at 17:06)</a>:</h4>
<blockquote>
<p>whether reordering mutations and function calls is something the compiler team has discussed permitting the optimizer to do</p>
</blockquote>
<p>It's something we proved correct for Stacked Borrows in <a href="https://plv.mpi-sws.org/rustbelt/stacked-borrows/">https://plv.mpi-sws.org/rustbelt/stacked-borrows/</a> :D</p>



<a name="200445549"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200445549" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200445549">(Jun 10 2020 at 17:06)</a>:</h4>
<p>but that doesnt model panics</p>



<a name="200445589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200445589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200445589">(Jun 10 2020 at 17:06)</a>:</h4>
<p>however, as mentioned above in this thread, moving the mutation down into both the normal-return and the unwind-return block ought to be a correct optimization</p>



<a name="200445846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200445846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200445846">(Jun 10 2020 at 17:08)</a>:</h4>
<p>does that answer the question?^^ I'll look at that PR tomorrow, and then maybe if you have a self-contained question assuming only knowledge that is described in that PR, that would help :D</p>



<a name="200446607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200446607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200446607">(Jun 10 2020 at 17:14)</a>:</h4>
<p>Yes, it does! Thanks. And, yes, I believe Niko's question in the PR comments only requires knowledge self-contained in the PR.</p>



<a name="200489116"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200489116" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200489116">(Jun 10 2020 at 23:03)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> Basically the issue that <code>longjmp</code> breaks that assumption since you are explicitly allowed to <code>longjmp</code> out of <code>nounwind</code> functions.</p>



<a name="200511945"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200511945" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200511945">(Jun 11 2020 at 07:16)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> that is quoting LLVM's rules, right? Rust could presumably have more restrictive rules and also limit what functions can be <code>longjump</code>ed out of?</p>



<a name="200512165"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200512165" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200512165">(Jun 11 2020 at 07:18)</a>:</h4>
<p>The LLVM rules are somewhat unclear, but I have to assume they allow <code>longjmp</code> since that's used in C code and C code is all compiled as <code>nounwind</code>.</p>



<a name="200516950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200516950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200516950">(Jun 11 2020 at 08:26)</a>:</h4>
<p>sure. but Rust is not bound to these rules. we can have functions that are <code>nounwindandnolongjmp</code>, and optimize MIR accordingly, even if LLVM IR cannot express this.</p>



<a name="200546743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200546743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200546743">(Jun 11 2020 at 13:52)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> I think that's right. The point is more that the rules we were on the point of proposing would, in fact, permit longjmp over frames that don't have destructors without any sort of "opt-in"</p>



<a name="200546768"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200546768" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200546768">(Jun 11 2020 at 13:53)</a>:</h4>
<p>But this seems to close a door that I'm not sure we want to close</p>



<a name="200546996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200546996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200546996">(Jun 11 2020 at 13:55)</a>:</h4>
<p>OTOH I'm not sure, the alternatives are kind of messy. One side note is that I remember now talking to <span class="user-mention" data-user-id="252446">@Yehuda Katz</span> some time back about how one might want compiler support to validate that if you invoke a fn that may longjmp, the compiler can check that no destructors are in scope (it's a "Plain Old Frame"...).</p>



<a name="200547172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200547172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200547172">(Jun 11 2020 at 13:56)</a>:</h4>
<p>Technically the main thing we've been trying to decide is what to do with <strong>panics</strong> that propagate (at least that's <span class="user-mention" data-user-id="237472">@acfoltzer</span>'s main interest). I guess we could leave longjmp for later work as part of this RFC and discuss it a bit more, though the constraints all remain sorta the same (e.g., existing functions in libc that are a pain, etc)</p>



<a name="200598036"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200598036" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200598036">(Jun 11 2020 at 20:01)</a>:</h4>
<p>It occurs to me that this optimization might be unsound even without <code>longjmp</code>. Consider the case where <code>x</code> points to a memory-mapped file and <code>bar</code> calls <code>exit()</code>. You would expect the write to <code>x</code> to be reflected in the file on exit, but that won't happen if the write is moved after the call.</p>



<a name="200601937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200601937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200601937">(Jun 11 2020 at 20:30)</a>:</h4>
<p>I'm not sure I would expect that, actually. Don't call <code>exit()</code> if you want cleanup to happen.</p>



<a name="200602048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200602048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200602048">(Jun 11 2020 at 20:31)</a>:</h4>
<p>File writes have tricky edge conditions.</p>



<a name="200624490"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200624490" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200624490">(Jun 12 2020 at 00:46)</a>:</h4>
<p>IMO any optimization moving globally visible side effects across a function call are only sound if that function call is guaranteed to eventually return normally.</p>



<a name="200646594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200646594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200646594">(Jun 12 2020 at 08:47)</a>:</h4>
<p>For writing memory mapped files you <strong>must</strong> to use <code>write_volatile</code>, as writing the memory has side-effects outside of the knowledge of the compiler. When you don't use <code>write_volatile</code>, the compiler is free to assume that writes don't have any side-effects other than affecting later reads of the same location. This means that the compiler is free to remove writes or insert spurious writes to memory locations it knows will never be read again, or only be read after a later write.</p>



<a name="200709080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200709080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200709080">(Jun 12 2020 at 18:45)</a>:</h4>
<p>That is not true. Accessing a memory mapped file is not a side-effect, you're just writing to memory that is shared with another thread (the kernel).</p>



<a name="200710701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200710701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200710701">(Jun 12 2020 at 18:58)</a>:</h4>
<p>You are right. For memory mapped files you should use atomic instructions, not volatile.</p>



<a name="200712648"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200712648" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vadim Petrochenkov <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200712648">(Jun 12 2020 at 19:16)</a>:</h4>
<p>That's pretty impractical though?<br>
One point  of mapping something into memory is to use some pre-existing or generic code reading or writing memory buffers.</p>



<a name="200712899"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200712899" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Vadim Petrochenkov <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200712899">(Jun 12 2020 at 19:18)</a>:</h4>
<p>I.e. using some separation of concerns - the "algorithmic" code just works with memory buffers, the "backend" code either maps those buffers into files directly, or e.g. zips those buffers and stores them to files in some other way.</p>



<a name="200714304"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200714304" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200714304">(Jun 12 2020 at 19:28)</a>:</h4>
<p>there's definitely a tension here, I don't know what I think yet. One thing I am thinking is that this discussion would benefit from bringing in more of the "unsafe code guidelines" regulars, more so than the relatively narrow ffi-unwind audience thus far. It feels clear that there is a "host of entangled patterns" going on here, and I'm guessing there's been some good conversation to dig up.</p>



<a name="200719859"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200719859" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200719859">(Jun 12 2020 at 20:19)</a>:</h4>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> You don't need to use atomics on mmaped files; they have a weak ordering model, and if you care about the ordering you have to call <code>msync</code> (or something else that requires consistency).</p>



<a name="200759346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200759346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200759346">(Jun 13 2020 at 10:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="143274">Amanieu</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200598036">said</a>:</p>
<blockquote>
<p>It occurs to me that this optimization might be unsound even without <code>longjmp</code>. Consider the case where <code>x</code> points to a memory-mapped file and <code>bar</code> calls <code>exit()</code>. You would expect the write to <code>x</code> to be reflected in the file on exit, but that won't happen if the write is moved after the call.</p>
</blockquote>
<p>that would break the <em>really fundamental</em> assumption that memory is an unobservable internal implementation detail that the compiler is free to optimize around, unless marked otherwise using things such as volatile.</p>



<a name="200759400"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200759400" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200759400">(Jun 13 2020 at 10:16)</a>:</h4>
<p>if mmaped files are allowed to communicate without such things, they must obey the aliasing rules</p>



<a name="200759413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200759413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200759413">(Jun 13 2020 at 10:17)</a>:</h4>
<p>and one of the rules is that an <code>&amp;mut</code> passed to a function must be a unique pointer until that function returns. if the function never returns for one reason or another, that means it must be a unique pointer forever.</p>



<a name="200759739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200759739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200759739">(Jun 13 2020 at 10:26)</a>:</h4>
<p>I guess we're back to the original issue then, does <code>exit</code> count as "returning" the same way <code>longjmp</code> does?</p>



<a name="200759750"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200759750" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200759750">(Jun 13 2020 at 10:26)</a>:</h4>
<p>yeah...</p>



<a name="200780615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200780615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200780615">(Jun 13 2020 at 19:10)</a>:</h4>
<p>It occurs to me that if we do allow the compiler to perform this optimization then it makes the whole POF concept useless: the compiler can arbitrarily add destructors where there are none by moving code after a function call and duplicating it on the unwind and normal return paths.</p>



<a name="200782441"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/200782441" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#200782441">(Jun 13 2020 at 19:43)</a>:</h4>
<p>At this point I believe that the POF concept will only be useful in conjunction with the "cancelable" annotation we plan to introduce.</p>



<a name="201027805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/201027805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#201027805">(Jun 16 2020 at 14:59)</a>:</h4>
<p>right, I wouldn't say that makes POF <em>useless</em></p>



<a name="201027820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/201027820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#201027820">(Jun 16 2020 at 14:59)</a>:</h4>
<p>it's "necessary but not sufficient"</p>



<a name="201471958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/201471958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#201471958">(Jun 20 2020 at 10:29)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> you mean in the sense that, adding code to the unwind path adds a destructor? good point.</p>



<a name="201472007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/UB%20to%20skip%20destructors/near/201472007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors.html#201472007">(Jun 20 2020 at 10:30)</a>:</h4>
<p>I guess there is a discussion to be had if this is an optimization that we want. I am really proud that Stacked Borrows can provide it, but there's clearly a trade-off. OTOH, this is an optimization that can benefit all code vs a rather niche feature. Still, worth a discussion it seems.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>